package com.abigdreamer.util;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.RenderingHints;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

public class ImageUtil
{
  public static BufferedImage zoomImage(BufferedImage img, int type, int rtype, int cw, int ch, int w, int h)
    throws Exception
  {
    ImageIcon iconImg = new ImageIcon(img);
    int bw = iconImg.getIconWidth();
    int bh = iconImg.getIconHeight();
    









    int zw = 0;
    int zh = 0;
    switch (rtype)
    {
    case 1: 
      zw = w - 2 * cw;
      zh = ch;
      break;
    case 2: 
      zw = cw;
      zh = h - 2 * ch;
      break;
    case 3: 
      zw = w - 2 * cw;
      zh = h - 2 * ch;
    }
    BufferedImage image = new BufferedImage(zw, zh, type);
    Graphics g = image.getGraphics();
    g.drawImage(img, 0, 0, zw, zh, 0, 0, bw, bh, null);
    
    return image;
  }
  
  public static BufferedImage mergeImage(int type, BufferedImage[] images, int w, int h)
    throws Exception
  {
    BufferedImage image = new BufferedImage(w, h, type);
    Graphics g = image.getGraphics();
    
    int x = 0;
    int y = 0;
    for (int i = 0; i < images.length; i++)
    {
      BufferedImage bimg = images[i];
      g.drawImage(bimg, x, y, bimg.getWidth(), bimg.getHeight(), null);
      if (i % 3 == 0) {
        x += bimg.getWidth();
      } else if (i % 3 == 1) {
        x += bimg.getWidth();
      } else if (i % 3 == 2) {
        x = 0;
      }
      if (i % 3 == 2) {
        y += bimg.getHeight();
      }
    }
    return image;
  }
  
  public static BufferedImage cut9Image(BufferedImage srcImg, int type, int cornerwidth, int cornerheight, int w, int h)
    throws Exception
  {
    BufferedImage[] images = new BufferedImage[9];
    List<BufferedImage> list = new ArrayList();
    
    int srcWidth = srcImg.getWidth();
    int srcHeight = srcImg.getHeight();
    
















    BufferedImage ltImg = new BufferedImage(cornerwidth, cornerheight, type);
    
    BufferedImage rtImg = new BufferedImage(cornerwidth, cornerheight, type);
    
    BufferedImage lbImg = new BufferedImage(cornerwidth, cornerheight, type);
    
    BufferedImage rbImg = new BufferedImage(cornerwidth, cornerheight, type);
    
    int tcWidth = srcWidth - 2 * cornerwidth;
    int tcHeight = cornerheight;
    
    BufferedImage tcImg = new BufferedImage(tcWidth, tcHeight, type);
    
    int lcWidth = cornerwidth;
    int lcHeight = srcHeight - 2 * cornerheight;
    
    BufferedImage lcImg = new BufferedImage(lcWidth, lcHeight, type);
    
    int midwidth = srcWidth - 2 * cornerwidth;
    int midheight = srcHeight - 2 * cornerheight;
    
    BufferedImage midbimg = new BufferedImage(midwidth, midheight, type);
    
    int rcWidth = cornerwidth;
    int rcHeight = srcHeight - 2 * cornerheight;
    
    BufferedImage rcImg = new BufferedImage(rcWidth, rcHeight, type);
    
    int bcWidth = srcWidth - 2 * cornerwidth;
    int bcHeight = cornerheight;
    
    BufferedImage bcImg = new BufferedImage(bcWidth, bcHeight, type);
    
    Graphics ltGraphics = ltImg.getGraphics();
    Graphics rtGraphics = rtImg.getGraphics();
    Graphics lbGraphics = lbImg.getGraphics();
    Graphics rbGraphics = rbImg.getGraphics();
    Graphics tcGraphics = tcImg.getGraphics();
    Graphics lcGraphics = lcImg.getGraphics();
    Graphics midGraphics = midbimg.getGraphics();
    Graphics rcGraphics = rcImg.getGraphics();
    Graphics bcGraphics = bcImg.getGraphics();
    
    String cutname = "";
    
    ltGraphics.drawImage(srcImg, 0, 0, cornerwidth, cornerheight, 0, 0, cornerwidth, cornerheight, null);
    

    images[0] = ltImg;
    list.add(ltImg);
    

    tcGraphics.drawImage(srcImg, 0, 0, tcWidth, tcHeight, cornerwidth, 0, cornerwidth + tcWidth, tcHeight, null);
    


    images[1] = zoomImage(tcImg, type, 1, cornerwidth, cornerheight, w, h);
    list.add(tcImg);
    

    rtGraphics.drawImage(srcImg, 0, 0, cornerwidth, cornerheight, cornerwidth + tcWidth, 0, 2 * cornerwidth + tcWidth, cornerheight, null);
    

    images[2] = rtImg;
    list.add(rtImg);
    

    lcGraphics.drawImage(srcImg, 0, 0, lcWidth, lcHeight, 0, cornerheight, 0 + lcWidth, cornerheight + lcHeight, null);
    


    images[3] = zoomImage(lcImg, type, 2, cornerwidth, cornerheight, w, h);
    list.add(lcImg);
    

    midGraphics.drawImage(srcImg, 0, 0, midwidth, midheight, cornerwidth, cornerheight, cornerwidth + midwidth, cornerheight + midheight, null);
    


    images[4] = zoomImage(midbimg, type, 3, cornerwidth, cornerheight, w, h);
    list.add(midbimg);
    

    rcGraphics.drawImage(srcImg, 0, 0, rcWidth, rcHeight, cornerwidth + midwidth, cornerheight, 2 * cornerwidth + midwidth, cornerheight + midheight, null);
    


    images[5] = zoomImage(rcImg, type, 2, cornerwidth, cornerheight, w, h);
    list.add(rcImg);
    

    lbGraphics.drawImage(srcImg, 0, 0, cornerwidth, cornerheight, 0, cornerheight + lcHeight, 0 + cornerwidth, 2 * cornerheight + lcHeight, null);
    

    images[6] = lbImg;
    list.add(lbImg);
    

    bcGraphics.drawImage(srcImg, 0, 0, bcWidth, bcHeight, cornerwidth, cornerheight + midheight, cornerwidth + bcWidth, 2 * cornerheight + midheight, null);
    


    images[7] = zoomImage(bcImg, type, 1, cornerwidth, cornerheight, w, h);
    list.add(bcImg);
    

    rbGraphics.drawImage(srcImg, 0, 0, cornerwidth, cornerheight, cornerwidth + bcWidth, cornerheight + rcHeight, 2 * cornerwidth + bcWidth, 2 * cornerheight + rcHeight, null);
    

    images[8] = rbImg;
    list.add(rbImg);
    
    return mergeImage(type, images, w, h);
  }
  
  public static BufferedImage getSubImage(Image image, int x, int y, int thumbWidth, int thumbHeight)
  {
    ImageIcon temp = new ImageIcon(image);
    int tempWidth = temp.getIconWidth();
    int tempHeight = temp.getIconHeight();
    
    BufferedImage thumbImage = new BufferedImage(tempWidth, tempHeight, 1);
    Graphics2D graphics2D = thumbImage.createGraphics();
    

    BufferedImage timage = graphics2D.getDeviceConfiguration().createCompatibleImage(tempWidth, tempHeight, 3);
    graphics2D.dispose();
    graphics2D = timage.createGraphics();
    

    graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
    graphics2D.drawImage(image, 0, 0, tempWidth, tempHeight, null);
    
    return timage.getSubimage(x, y, thumbWidth, thumbHeight);
  }
  
  public static BufferedImage createThumbnail(Image image, int thumbWidth, int thumbHeight, int quality)
    throws InterruptedException, FileNotFoundException, IOException
  {
    MediaTracker mediaTracker = new MediaTracker(new Container());
    mediaTracker.addImage(image, 0);
    mediaTracker.waitForID(0);
    


    double thumbRatio = thumbWidth / thumbHeight;
    int imageWidth = image.getWidth(null);
    int imageHeight = image.getHeight(null);
    double imageRatio = imageWidth / imageHeight;
    if (thumbRatio < imageRatio) {
      thumbHeight = (int)(thumbWidth / imageRatio);
    } else {
      thumbWidth = (int)(thumbHeight * imageRatio);
    }
    BufferedImage thumbImage = new BufferedImage(thumbWidth, thumbHeight, 1);
    Graphics2D graphics2D = thumbImage.createGraphics();
    

    BufferedImage timage = graphics2D.getDeviceConfiguration().createCompatibleImage(thumbWidth, thumbHeight, 3);
    graphics2D.dispose();
    graphics2D = timage.createGraphics();
    

    graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
    graphics2D.drawImage(image, 0, 0, thumbWidth, thumbHeight, null);
    
    return timage;
  }
  
  public static void createThumbnail(Image image, int thumbWidth, int thumbHeight, int quality, String outFilename)
    throws InterruptedException, FileNotFoundException, IOException
  {
    BufferedImage thumbImage = createThumbnail(image, thumbWidth, thumbHeight, quality);
    
    BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(outFilename));
    JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
    JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(thumbImage);
    quality = Math.max(0, Math.min(quality, 100));
    param.setQuality(quality / 100.0F, false);
    encoder.setJPEGEncodeParam(param);
    encoder.encode(thumbImage);
    out.close();
  }
  
  public static BufferedImage makeRoundedCorner(BufferedImage image, int cornerRadius)
  {
    int w = image.getWidth();
    int h = image.getHeight();
    BufferedImage output = new BufferedImage(w, h, 2);
    
    Graphics2D g2 = output.createGraphics();
    





    g2.setComposite(AlphaComposite.Src);
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2.setColor(Color.WHITE);
    g2.fill(new RoundRectangle2D.Float(0.0F, 0.0F, w, h, cornerRadius, cornerRadius));
    


    g2.setComposite(AlphaComposite.SrcAtop);
    g2.drawImage(image, 0, 0, null);
    
    g2.dispose();
    
    return output;
  }
  
  public static BufferedImage createResizedCopy(Image originalImage, int scaledWidth, int scaledHeight, boolean preserveAlpha)
  {
    int imageType = preserveAlpha ? 1 : 2;
    BufferedImage scaledBI = new BufferedImage(scaledWidth, scaledHeight, imageType);
    Graphics2D g = scaledBI.createGraphics();
    if (preserveAlpha) {
      g.setComposite(AlphaComposite.Src);
    }
    g.drawImage(originalImage, 0, 0, scaledWidth, scaledHeight, null);
    g.dispose();
    return scaledBI;
  }
  
  public static void main(String[] args)
    throws IOException
  {
    BufferedImage pic = ImageIO.read(new File("C:\\Users\\Darkness\\Desktop\\main_search_bkg.png"));
    BufferedImage resized = createResizedCopy(pic, 200, 35, false);
    ImageIO.write(resized, "png", new File("C:\\Users\\Darkness\\Desktop\\zhang_small.jpg"));
  }
}
